{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:10.380130Z",
     "start_time": "2019-10-20T06:48:09.143837Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/amax/myproject-env/tf1_9/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:523: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "/home/amax/myproject-env/tf1_9/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:524: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "/home/amax/myproject-env/tf1_9/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "/home/amax/myproject-env/tf1_9/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "/home/amax/myproject-env/tf1_9/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:527: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "/home/amax/myproject-env/tf1_9/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:532: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "import os\n",
    "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"1\"\n",
    "config =  tf.ConfigProto() \n",
    "config.gpu_options.per_process_gpu_memory_fraction = 0.5 # 占用GPU30%的显存 \n",
    "session = tf.Session(config=config)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:11.574314Z",
     "start_time": "2019-10-20T06:48:11.493863Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from __future__ import division\n",
    "import random\n",
    "import pprint\n",
    "import sys\n",
    "import time\n",
    "import numpy as np\n",
    "from optparse import OptionParser\n",
    "import pickle\n",
    "import os\n",
    "import cv2\n",
    "import xml.etree.ElementTree as ET\n",
    "from tqdm import tqdm\n",
    "\n",
    "from keras import backend as K\n",
    "from keras.optimizers import Adam, SGD, RMSprop\n",
    "from keras.layers import Input\n",
    "from keras.models import Model\n",
    "\n",
    "from keras.utils import generic_utils\n",
    "from keras.callbacks import TensorBoard"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:12.067300Z",
     "start_time": "2019-10-20T06:48:12.060213Z"
    }
   },
   "outputs": [],
   "source": [
    "import resnet50 as nn\n",
    "import losses "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:12.861240Z",
     "start_time": "2019-10-20T06:48:12.858279Z"
    },
    "code_folding": []
   },
   "outputs": [],
   "source": [
    "# \n",
    "# import random\n",
    "# with open(\"VOC2012/ImageSets/Main/train2.txt\",\"r\") as fp:\n",
    "#     x = fp.readlines()\n",
    "#     random.shuffle(x)\n",
    "\n",
    "# with open(\"VOC2012/ImageSets/Main/train1.txt\",\"w\") as fp:\n",
    "#     fp.writelines(x)\n",
    "    \n",
    "# with open(\"VOC2012/ImageSets/Main/trainval.txt\",\"w\") as fp:\n",
    "#     fp.writelines(x[0:7680])\n",
    "\n",
    "# with open(\"VOC2012/ImageSets/Main/train.txt\",\"w\") as fp:\n",
    "#     fp.writelines(x[0:5120])\n",
    "\n",
    "# with open(\"VOC2012/ImageSets/Main/val.txt\",\"w\") as fp:\n",
    "#     fp.writelines(x[5120:7680])\n",
    "\n",
    "# with open(\"VOC2012/ImageSets/Main/test.txt\",\"w\") as fp:\n",
    "#     fp.writelines(x[7680:10240])\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 参数初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:13.930714Z",
     "start_time": "2019-10-20T06:48:13.919198Z"
    }
   },
   "outputs": [],
   "source": [
    "# 设置递归深度的限制\n",
    "sys.setrecursionlimit(40000)\n",
    "\n",
    "verbose = True\n",
    "network = 'resnet50'\n",
    "\n",
    "use_horizontal_flips = False\n",
    "use_vertical_flips = False\n",
    "rot_90 = False\n",
    "\n",
    "anchor_box_scales = [128, 256, 512]\n",
    "anchor_box_ratios = [[1, 1], [1, 2], [2, 1]]\n",
    "\n",
    "im_size = 600\n",
    "img_channel_mean = [103.939, 116.779, 123.68]\n",
    "img_scaling_factor = 1.0\n",
    "num_rois = 300\n",
    "rpn_stride = 16\n",
    "balanced_classes = False\n",
    "std_scaling = 4.0\n",
    "classifier_regr_std = [8.0, 8.0, 4.0, 4.0]\n",
    "rpn_min_overlap = 0.3\n",
    "rpn_max_overlap = 0.7\n",
    "\n",
    "classifier_min_overlap = 0.1\n",
    "classifier_max_overlap = 0.5\n",
    "class_mapping = None\n",
    "model_path = './model_frcnn_resnet_face.hdf5'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:14.525528Z",
     "start_time": "2019-10-20T06:48:14.519487Z"
    }
   },
   "outputs": [],
   "source": [
    "# VOC2012文件夹所在路径"
    "train_path = \"widerface/\"\n",
    "parser =\"pascal_voc\"\n",
    "num_rois = 32\n",
    "network = 'resnet50'\n",
    "\n",
    "horizontal_flips = False\n",
    "vertical_flips = False\n",
    "rot_90 = False\n",
    "num_epochs = 10\n",
    "config_filename = \"config.pickle\"\n",
    "output_weight_path = './model_frcnn_face.hdf5'\n",
    "input_weight_path = \"resnet50_weights_tf_dim_ordering_tf_kernels.h5\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据导入"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:41.303818Z",
     "start_time": "2019-10-20T06:48:16.074948Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Processing 002357.xml:   0%|          | 45/12876 [00:00<00:28, 443.01it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parsing annotation files\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Processing 008635.xml: 100%|██████████| 12876/12876 [00:25<00:00, 512.33it/s]\n"
     ]
    }
   ],
   "source": [
    "def get_data(input_path):\n",
    "    all_imgs = []\n",
    "    classes_count = {}\n",
    "    # 类别映射\n",
    "    class_mapping = {}\n",
    "\n",
    "    visualise = False\n",
    "\n",
    "    # pascal voc directory + 2012\n",
    "    data_paths = [os.path.join(input_path, 'VOC2012')]\n",
    "\n",
    "    print('Parsing annotation files')\n",
    "    for data_path in data_paths:\n",
    "\n",
    "        annot_path = os.path.join(data_path, 'Annotations')\n",
    "        imgs_path = os.path.join(data_path, 'JPEGImages')\n",
    "\n",
    "        #ImageSets/Main directory(train, val, trainval, test)\n",
    "        imgsets_path_trainval = os.path.join(data_path, 'ImageSets', 'Main', 'trainval.txt')\n",
    "        imgsets_path_train = os.path.join(data_path, 'ImageSets', 'Main', 'train.txt')\n",
    "        imgsets_path_val = os.path.join(data_path, 'ImageSets', 'Main', 'val.txt')\n",
    "        imgsets_path_test = os.path.join(data_path, 'ImageSets', 'Main', 'test.txt')\n",
    "\n",
    "        trainval_files = []\n",
    "        train_files = []\n",
    "        val_files = []\n",
    "        test_files = []\n",
    "\n",
    "        with open(imgsets_path_trainval) as f:\n",
    "            for line in f:\n",
    "                trainval_files.append(line.strip() + '.jpg')\n",
    "\n",
    "        with open(imgsets_path_train) as f:\n",
    "            for line in f:\n",
    "                train_files.append(line.strip() + '.jpg')\n",
    "\n",
    "        with open(imgsets_path_val) as f:\n",
    "            for line in f:\n",
    "                val_files.append(line.strip() + '.jpg')\n",
    "\n",
    "        # test-set not included in pascal VOC 2012\n",
    "        if os.path.isfile(imgsets_path_test):\n",
    "            with open(imgsets_path_test) as f:\n",
    "                for line in f:\n",
    "                    test_files.append(line.strip() + '.jpg')\n",
    "\n",
    "        annots = [os.path.join(annot_path, s) for s in os.listdir(annot_path)]\n",
    "        idx = 0\n",
    "\n",
    "        annots = tqdm(annots)\n",
    "        for annot in annots:\n",
    "            # try:\n",
    "            exist_flag = False\n",
    "            idx += 1\n",
    "            annots.set_description(\"Processing %s\" % annot.split(os.sep)[-1])\n",
    "\n",
    "            et = ET.parse(annot)\n",
    "            element = et.getroot()\n",
    "\n",
    "            element_objs = element.findall('object')\n",
    "            element_filename = element.find('filename').text\n",
    "            element_width = int(element.find('size').find('width').text)\n",
    "            element_height = int(element.find('size').find('height').text)\n",
    "\n",
    "            if len(element_objs) > 0:\n",
    "                annotation_data = {'filepath': os.path.join(imgs_path, element_filename), 'width': element_width,\n",
    "                                   'height': element_height, 'bboxes': []}\n",
    "\n",
    "                annotation_data['image_id'] = idx\n",
    "\n",
    "                if element_filename in trainval_files:\n",
    "                    annotation_data['imageset'] = 'trainval'\n",
    "                    exist_flag = True\n",
    "\n",
    "                if element_filename in train_files:\n",
    "                    annotation_data['imageset'] = 'train'\n",
    "                    exist_flag = True\n",
    "\n",
    "                if element_filename in val_files:\n",
    "                    annotation_data['imageset'] = 'val'\n",
    "                    exist_flag = True\n",
    "\n",
    "                if len(test_files) > 0:\n",
    "                    if element_filename in test_files:\n",
    "                        annotation_data['imageset'] = 'test'\n",
    "                        exist_flag = True\n",
    "\n",
    "                    \n",
    "\n",
    "            # annotation file not exist in ImageSet\n",
    "            if not exist_flag:\n",
    "                continue\n",
    "\n",
    "            for element_obj in element_objs:\n",
    "                class_name = element_obj.find('name').text\n",
    "                if class_name not in classes_count:\n",
    "                    classes_count[class_name] = 1\n",
    "                else:\n",
    "                    classes_count[class_name] += 1\n",
    "\n",
    "                # class mapping \n",
    "                if class_name not in class_mapping:\n",
    "                    class_mapping[class_name] = len(class_mapping) \n",
    "\n",
    "                obj_bbox = element_obj.find('bndbox')\n",
    "                x1 = int(round(float(obj_bbox.find('xmin').text)))\n",
    "                y1 = int(round(float(obj_bbox.find('ymin').text)))\n",
    "                x2 = int(round(float(obj_bbox.find('xmax').text)))\n",
    "                y2 = int(round(float(obj_bbox.find('ymax').text)))\n",
    "                difficulty = int(element_obj.find('difficult').text) == 1\n",
    "                annotation_data['bboxes'].append(\n",
    "                    {'class': class_name, 'x1': x1, 'x2': x2, 'y1': y1, 'y2': y2, 'difficult': difficulty})\n",
    "            all_imgs.append(annotation_data)\n",
    "\n",
    "            if visualise:\n",
    "                img = cv2.imread(annotation_data['filepath'])\n",
    "                for bbox in annotation_data['bboxes']:\n",
    "                    cv2.rectangle(img, (bbox['x1'], bbox['y1']), (bbox['x2'], bbox['y2']), (0, 0, 255))\n",
    "                cv2.imshow('img', img)\n",
    "                print(annotation_data['imageset'])\n",
    "                cv2.waitKey(0)\n",
    "\n",
    "            # except Exception as e:\n",
    "            #     print(e)\n",
    "            #     continue\n",
    "    return all_imgs, classes_count, class_mapping\n",
    "\n",
    "all_imgs, classes_count, class_mapping = get_data(train_path)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:41.311651Z",
     "start_time": "2019-10-20T06:48:41.306304Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10240 {'face': 125507} {'face': 0}\n"
     ]
    }
   ],
   "source": [
    "print(len(all_imgs),classes_count,class_mapping)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:41.359655Z",
     "start_time": "2019-10-20T06:48:41.315673Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training images per class:\n",
      "{'bg': 0, 'face': 125507}\n",
      "Num classes (including bg) = 2\n",
      "Num train samples 5120\n",
      "Num val samples 2560\n",
      "Num test samples 2560\n"
     ]
    }
   ],
   "source": [
    "# 如果没有背景类，加入背景类\n",
    "if 'bg' not in classes_count:\n",
    "    classes_count['bg'] = 0\n",
    "    class_mapping['bg'] = len(class_mapping)\n",
    "\n",
    "# 将class_mapping的值和键翻转\n",
    "inv_map = {v: k for k, v in class_mapping.items()}\n",
    "\n",
    "print('Training images per class:')\n",
    "pprint.pprint(classes_count)\n",
    "print('Num classes (including bg) = {}'.format(len(classes_count)))\n",
    "\n",
    "# 打乱数据\n",
    "random.shuffle(all_imgs)\n",
    "\n",
    "num_imgs = len(all_imgs)\n",
    "\n",
    "train_imgs = [s for s in all_imgs if s['imageset'] == 'train']\n",
    "val_imgs = [s for s in all_imgs if s['imageset'] == 'val']\n",
    "test_imgs = [s for s in all_imgs if s['imageset'] == 'test']\n",
    "\n",
    "#显示训练集，验证集，测试集的数量\n",
    "print('Num train samples {}'.format(len(train_imgs)))\n",
    "print('Num val samples {}'.format(len(val_imgs)))\n",
    "print('Num test samples {}'.format(len(test_imgs)))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:41.370227Z",
     "start_time": "2019-10-20T06:48:41.362681Z"
    }
   },
   "outputs": [],
   "source": [
    "# 数据增强\n",
    "import data_generator\n",
    "import resnet50 as nn\n",
    "data_gen_train = data_generator.get_anchor_gt(train_imgs, classes_count,nn.get_img_output_length,mode='train')\n",
    "data_gen_val = data_generator.get_anchor_gt(val_imgs, classes_count, nn.get_img_output_length,mode='val')\n",
    "data_gen_test = data_generator.get_anchor_gt(test_imgs, classes_count,nn.get_img_output_length, mode='val')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 搭建网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:43.829973Z",
     "start_time": "2019-10-20T06:48:41.372583Z"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# placeholder\n",
    "input_shape_img = (None, None, 3)\n",
    "\n",
    "img_input = Input(shape=input_shape_img)\n",
    "roi_input = Input(shape=(None, 4))\n",
    "\n",
    "shared_layers = nn.nn_base(img_input, trainable=True)\n",
    "anchor_box_scales = [128, 256, 512]\n",
    "anchor_box_ratios = [[1, 1], [1, 2], [2, 1]]\n",
    "num_anchors = len(anchor_box_scales) * len(anchor_box_ratios)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:43.840168Z",
     "start_time": "2019-10-20T06:48:43.834121Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9\n"
     ]
    }
   ],
   "source": [
    "print(num_anchors)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:52.683750Z",
     "start_time": "2019-10-20T06:48:43.843274Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loading weights from resnet50_weights_tf_dim_ordering_tf_kernels.h5\n"
     ]
    }
   ],
   "source": [
    "rpn = nn.rpn(shared_layers, num_anchors)\n",
    "\n",
    "classifier = nn.classifier(shared_layers, roi_input, num_rois, nb_classes=len(classes_count), trainable=True)\n",
    "\n",
    "model_rpn = Model(img_input, rpn[:2])\n",
    "model_classifier = Model([img_input, roi_input], classifier)\n",
    "\n",
    "model_all = Model([img_input, roi_input], rpn[:2] + classifier)\n",
    "\n",
    "# 此处最好先下载好模型，初始化模型的位置input_weight_path\n",
    "base_net_weights = input_weight_path\n",
    "try:\n",
    "    print('loading weights from {}'.format(base_net_weights))\n",
    "    model_rpn.load_weights(base_net_weights, by_name=True)\n",
    "    model_classifier.load_weights(base_net_weights, by_name=True)\n",
    "except:\n",
    "    print('Could not load pretrained model weights. Weights can be found in the keras application folder \\\n",
    "        https://github.com/fchollet/keras/tree/master/keras/applications')\n",
    "\n",
    "# 编译\n",
    "optimizer = Adam(lr=1e-5)\n",
    "optimizer_classifier = Adam(lr=1e-5)\n",
    "model_rpn.compile(optimizer=optimizer, loss=[losses.rpn_loss_cls(num_anchors), losses.rpn_loss_regr(num_anchors)])\n",
    "model_classifier.compile(optimizer=optimizer_classifier, loss=[losses.class_loss_cls, losses.class_loss_regr(len(classes_count)-1)], metrics={'dense_class_{}'.format(len(classes_count)): 'accuracy'})\n",
    "model_all.compile(optimizer='sgd', loss='mae')\n",
    "\n",
    "# tensorboard\n",
    "log_path = './logs'\n",
    "if not os.path.isdir(log_path):\n",
    "    os.mkdir(log_path)\n",
    "    \n",
    "callback = TensorBoard(log_path)\n",
    "callback.set_model(model_all)\n",
    "\n",
    "def write_log(callback, names, logs, batch_no):\n",
    "    for name, value in zip(names, logs):\n",
    "        summary = tf.Summary()\n",
    "        summary_value = summary.value.add()\n",
    "        summary_value.simple_value = value\n",
    "        summary_value.tag = name\n",
    "        callback.writer.add_summary(summary, batch_no)\n",
    "        callback.writer.flush()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:52.696992Z",
     "start_time": "2019-10-20T06:48:52.690409Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'face': 0, 'bg': 1}\n"
     ]
    }
   ],
   "source": [
    "class_mapping = {'bg': 1, 'face': 0}\n",
    "print(class_mapping)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:52.709434Z",
     "start_time": "2019-10-20T06:48:52.700501Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Starting training\n"
     ]
    }
   ],
   "source": [
    "epoch_length = 512\n",
    "num_epochs = int(num_epochs)\n",
    "iter_num = 0\n",
    "train_step = 0\n",
    "\n",
    "losses = np.zeros((epoch_length, 5))\n",
    "rpn_accuracy_rpn_monitor = []\n",
    "rpn_accuracy_for_epoch = []\n",
    "start_time = time.time()\n",
    "\n",
    "best_loss = np.Inf\n",
    "\n",
    "class_mapping_inv = {v: k for k, v in class_mapping.items()}\n",
    "print('Starting training')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T06:48:52.719274Z",
     "start_time": "2019-10-20T06:48:52.712182Z"
    }
   },
   "outputs": [],
   "source": [
    "import roi_helpers "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T23:02:30.717594Z",
     "start_time": "2019-10-20T14:24:05.360257Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "478/512 [===========================>..] - ETA: 11s - rpn_cls: 2.7094 - rpn_regr: 0.5559 - detector_cls: 0.1791 - detector_regr: 0.1468Exception: 'a' cannot be empty unless no samples are taken\n",
      "501/512 [============================>.] - ETA: 6s - rpn_cls: 2.7080 - rpn_regr: 0.5563 - detector_cls: 0.1791 - detector_regr: 0.1470Average number of overlapping bounding boxes from RPN = 1.20703125 for 512 previous iterations\n",
      "512/512 [==============================] - 377s 735ms/step - rpn_cls: 2.7074 - rpn_regr: 0.5565 - detector_cls: 0.1791 - detector_regr: 0.1472\n",
      "Mean number of bounding boxes from RPN overlapping ground truth boxes: 1.0801526717557253\n",
      "Classifier accuracy for bounding boxes from RPN: 0.94940185546875\n",
      "Loss RPN classifier: 2.6838666341316535\n",
      "Loss RPN regression: 0.5603940585669989\n",
      "Loss Detector classifier: 0.17908048526351195\n",
      "Loss Detector regression: 0.15265284777706256\n",
      "Elapsed time: 3496.245603084564\n",
      "Total loss decreased from 3.7208107451405965 to 3.575994025739227, saving weights\n",
      "Epoch 2/10\n",
      "101/512 [====>.........................] - ETA: 41:36 - rpn_cls: 2.5425 - rpn_regr: 0.5931 - detector_cls: 0.1906 - detector_regr: 0.1658Exception: 'a' cannot be empty unless no samples are taken\n",
      "261/512 [==============>...............] - ETA: 26:53 - rpn_cls: 2.5114 - rpn_regr: 0.5622 - detector_cls: 0.2016 - detector_regr: 0.1734Exception: 'a' cannot be empty unless no samples are taken\n",
      "346/512 [===================>..........] - ETA: 18:00 - rpn_cls: 2.5065 - rpn_regr: 0.5581 - detector_cls: 0.2028 - detector_regr: 0.1725Average number of overlapping bounding boxes from RPN = 1.416015625 for 512 previous iterations\n",
      "355/512 [===================>..........] - ETA: 17:01 - rpn_cls: 2.5067 - rpn_regr: 0.5574 - detector_cls: 0.2029 - detector_regr: 0.1724Exception: 'a' cannot be empty unless no samples are taken\n",
      "482/512 [===========================>..] - ETA: 3:14 - rpn_cls: 2.5257 - rpn_regr: 0.5525 - detector_cls: 0.2029 - detector_regr: 0.1729Exception: 'a' cannot be empty unless no samples are taken\n",
      "512/512 [==============================] - 3315s 6s/step - rpn_cls: 2.5308 - rpn_regr: 0.5515 - detector_cls: 0.2026 - detector_regr: 0.1728\n",
      "Mean number of bounding boxes from RPN overlapping ground truth boxes: 1.3640054127198917\n",
      "Classifier accuracy for bounding boxes from RPN: 0.9412841796875\n",
      "Loss RPN classifier: 2.6127369963561016\n",
      "Loss RPN regression: 0.5361139078022461\n",
      "Loss Detector classifier: 0.19720460563650777\n",
      "Loss Detector regression: 0.1710696026198093\n",
      "Elapsed time: 3315.8314538002014\n",
      "Total loss decreased from 3.575994025739227 to 3.5171251124146647, saving weights\n",
      "Epoch 3/10\n",
      " 51/512 [=>............................] - ETA: 50:53 - rpn_cls: 2.9040 - rpn_regr: 0.5752 - detector_cls: 0.2091 - detector_regr: 0.1899Exception: 'a' cannot be empty unless no samples are taken\n",
      " 89/512 [====>.........................] - ETA: 49:05 - rpn_cls: 2.6988 - rpn_regr: 0.5673 - detector_cls: 0.2041 - detector_regr: 0.1757Exception: 'a' cannot be empty unless no samples are taken\n",
      "160/512 [========>.....................] - ETA: 41:37 - rpn_cls: 2.6162 - rpn_regr: 0.5665 - detector_cls: 0.1951 - detector_regr: 0.1591Exception: 'a' cannot be empty unless no samples are taken\n",
      "173/512 [=========>....................] - ETA: 39:44 - rpn_cls: 2.6060 - rpn_regr: 0.5670 - detector_cls: 0.1944 - detector_regr: 0.1582Average number of overlapping bounding boxes from RPN = 1.193359375 for 512 previous iterations\n",
      "248/512 [=============>................] - ETA: 30:15 - rpn_cls: 2.5744 - rpn_regr: 0.5694 - detector_cls: 0.1917 - detector_regr: 0.1538Exception: 'a' cannot be empty unless no samples are taken\n",
      "272/512 [==============>...............] - ETA: 27:29 - rpn_cls: 2.5710 - rpn_regr: 0.5701 - detector_cls: 0.1907 - detector_regr: 0.1526Exception: 'a' cannot be empty unless no samples are taken\n",
      "489/512 [===========================>..] - ETA: 2:40 - rpn_cls: 2.5685 - rpn_regr: 0.5706 - detector_cls: 0.1893 - detector_regr: 0.1519Average number of overlapping bounding boxes from RPN = 1.01953125 for 512 previous iterations\n",
      "512/512 [==============================] - 3532s 7s/step - rpn_cls: 2.5693 - rpn_regr: 0.5706 - detector_cls: 0.1892 - detector_regr: 0.1520\n",
      "Mean number of bounding boxes from RPN overlapping ground truth boxes: 1.0518518518518518\n",
      "Classifier accuracy for bounding boxes from RPN: 0.94866943359375\n",
      "Loss RPN classifier: 2.576014095749187\n",
      "Loss RPN regression: 0.5680564959884578\n",
      "Loss Detector classifier: 0.1855090243416555\n",
      "Loss Detector regression: 0.15606078252221778\n",
      "Elapsed time: 3532.2211949825287\n",
      "Total loss decreased from 3.5171251124146647 to 3.485640398601518, saving weights\n",
      "Epoch 4/10\n",
      "  5/512 [..............................] - ETA: 51:36 - rpn_cls: 1.2131 - rpn_regr: 0.2620 - detector_cls: 0.0216 - detector_regr: 0.0000e+00     Exception: 'a' cannot be empty unless no samples are taken\n",
      " 96/512 [====>.........................] - ETA: 42:36 - rpn_cls: 2.2206 - rpn_regr: 0.5261 - detector_cls: 0.1047 - detector_regr: 0.0876Exception: 'a' cannot be empty unless no samples are taken\n",
      "167/512 [========>.....................] - ETA: 38:38 - rpn_cls: 2.3849 - rpn_regr: 0.5390 - detector_cls: 0.1152 - detector_regr: 0.1024Exception: 'a' cannot be empty unless no samples are taken\n",
      "204/512 [==========>...................] - ETA: 34:10 - rpn_cls: 2.4134 - rpn_regr: 0.5422 - detector_cls: 0.1207 - detector_regr: 0.1076Exception: 'a' cannot be empty unless no samples are taken\n",
      "273/512 [==============>...............] - ETA: 26:10 - rpn_cls: 2.4208 - rpn_regr: 0.5467 - detector_cls: 0.1290 - detector_regr: 0.1164Exception: 'a' cannot be empty unless no samples are taken\n",
      "348/512 [===================>..........] - ETA: 17:50 - rpn_cls: 2.4264 - rpn_regr: 0.5475 - detector_cls: 0.1354 - detector_regr: 0.1220Average number of overlapping bounding boxes from RPN = 1.09375 for 512 previous iterations\n",
      "382/512 [=====================>........] - ETA: 14:01 - rpn_cls: 2.4277 - rpn_regr: 0.5474 - detector_cls: 0.1379 - detector_regr: 0.1238Exception: 'a' cannot be empty unless no samples are taken\n",
      "451/512 [=========================>....] - ETA: 6:38 - rpn_cls: 2.4197 - rpn_regr: 0.5488 - detector_cls: 0.1425 - detector_regr: 0.1267Exception: 'a' cannot be empty unless no samples are taken\n",
      "462/512 [==========================>...] - ETA: 5:27 - rpn_cls: 2.4185 - rpn_regr: 0.5492 - detector_cls: 0.1432 - detector_regr: 0.1271Exception: 'a' cannot be empty unless no samples are taken\n",
      "512/512 [==============================] - 3330s 7s/step - rpn_cls: 2.4175 - rpn_regr: 0.5515 - detector_cls: 0.1463 - detector_regr: 0.1287\n",
      "Mean number of bounding boxes from RPN overlapping ground truth boxes: 1.2976356050069542\n",
      "Classifier accuracy for bounding boxes from RPN: 0.94525146484375\n",
      "Loss RPN classifier: 2.411370510043895\n",
      "Loss RPN regression: 0.5745413917215956\n",
      "Loss Detector classifier: 0.17739654288864415\n",
      "Loss Detector regression: 0.1450635193407379\n",
      "Elapsed time: 3331.1663734912872\n",
      "Total loss decreased from 3.485640398601518 to 3.3083719639948725, saving weights\n",
      "Epoch 5/10\n",
      "197/512 [==========>...................] - ETA: 33:43 - rpn_cls: 2.4623 - rpn_regr: 0.5755 - detector_cls: 0.1676 - detector_regr: 0.1251Average number of overlapping bounding boxes from RPN = 1.408203125 for 512 previous iterations\n",
      "229/512 [============>.................] - ETA: 31:47 - rpn_cls: 2.4654 - rpn_regr: 0.5707 - detector_cls: 0.1674 - detector_regr: 0.1257Exception: 'a' cannot be empty unless no samples are taken\n",
      "512/512 [==============================] - 3412s 7s/step - rpn_cls: 2.4559 - rpn_regr: 0.5513 - detector_cls: 0.1654 - detector_regr: 0.1306\n",
      "Mean number of bounding boxes from RPN overlapping ground truth boxes: 1.2208672086720866\n",
      "Classifier accuracy for bounding boxes from RPN: 0.94769287109375\n",
      "Loss RPN classifier: 2.456321351424134\n",
      "Loss RPN regression: 0.5348740154967118\n",
      "Loss Detector classifier: 0.16951737087954477\n",
      "Loss Detector regression: 0.138561056067374\n",
      "Elapsed time: 3412.479733467102\n",
      "Total loss decreased from 3.3083719639948725 to 3.2992737938677648, saving weights\n",
      "Epoch 6/10\n",
      " 34/512 [>.............................] - ETA: 48:54 - rpn_cls: 3.4001 - rpn_regr: 0.5816 - detector_cls: 0.1091 - detector_regr: 0.0702Average number of overlapping bounding boxes from RPN = 1.1953125 for 512 previous iterations\n",
      " 73/512 [===>..........................] - ETA: 50:46 - rpn_cls: 3.0958 - rpn_regr: 0.6259 - detector_cls: 0.1295 - detector_regr: 0.0819Exception: 'a' cannot be empty unless no samples are taken\n",
      "232/512 [============>.................] - ETA: 30:36 - rpn_cls: 2.7186 - rpn_regr: 0.6004 - detector_cls: 0.1600 - detector_regr: 0.1164Exception: 'a' cannot be empty unless no samples are taken\n",
      "283/512 [===============>..............] - ETA: 25:37 - rpn_cls: 2.6958 - rpn_regr: 0.5905 - detector_cls: 0.1643 - detector_regr: 0.1202Exception: 'a' cannot be empty unless no samples are taken\n",
      "380/512 [=====================>........] - ETA: 14:41 - rpn_cls: 2.6638 - rpn_regr: 0.5749 - detector_cls: 0.1682 - detector_regr: 0.1250Average number of overlapping bounding boxes from RPN = 1.423828125 for 512 previous iterations\n",
      "395/512 [======================>.......] - ETA: 13:00 - rpn_cls: 2.6603 - rpn_regr: 0.5732 - detector_cls: 0.1686 - detector_regr: 0.1255Exception: 'a' cannot be empty unless no samples are taken\n",
      "450/512 [=========================>....] - ETA: 6:49 - rpn_cls: 2.6509 - rpn_regr: 0.5685 - detector_cls: 0.1696 - detector_regr: 0.1277Exception: 'a' cannot be empty unless no samples are taken\n",
      "512/512 [==============================] - 3359s 7s/step - rpn_cls: 2.6421 - rpn_regr: 0.5645 - detector_cls: 0.1701 - detector_regr: 0.1299\n",
      "Mean number of bounding boxes from RPN overlapping ground truth boxes: 1.2938829787234043\n",
      "Classifier accuracy for bounding boxes from RPN: 0.94573974609375\n",
      "Loss RPN classifier: 2.5985728383816085\n",
      "Loss RPN regression: 0.5360177587417638\n",
      "Loss Detector classifier: 0.17236215225153728\n",
      "Loss Detector regression: 0.1442849769755412\n",
      "Elapsed time: 3359.3406150341034\n",
      "Epoch 7/10\n",
      "  5/512 [..............................] - ETA: 39:51 - rpn_cls: 2.0512 - rpn_regr: 0.4775 - detector_cls: 0.2756 - detector_regr: 0.2088Exception: 'a' cannot be empty unless no samples are taken\n",
      " 53/512 [==>...........................] - ETA: 52:58 - rpn_cls: 2.5219 - rpn_regr: 0.3888 - detector_cls: 0.1870 - detector_regr: 0.1493Exception: 'a' cannot be empty unless no samples are taken\n",
      " 73/512 [===>..........................] - ETA: 52:08 - rpn_cls: 2.5354 - rpn_regr: 0.4063 - detector_cls: 0.1803 - detector_regr: 0.1404Exception: 'a' cannot be empty unless no samples are taken\n",
      " 80/512 [===>..........................] - ETA: 50:49 - rpn_cls: 2.5434 - rpn_regr: 0.4163 - detector_cls: 0.1785 - detector_regr: 0.1385Exception: 'a' cannot be empty unless no samples are taken\n",
      "208/512 [===========>..................] - ETA: 34:37 - rpn_cls: 2.6100 - rpn_regr: 0.4834 - detector_cls: 0.1687 - detector_regr: 0.1317Average number of overlapping bounding boxes from RPN = 1.23828125 for 512 previous iterations\n",
      "308/512 [=================>............] - ETA: 22:30 - rpn_cls: 2.5991 - rpn_regr: 0.4936 - detector_cls: 0.1692 - detector_regr: 0.1339Exception: 'a' cannot be empty unless no samples are taken\n",
      "Exception: 'a' cannot be empty unless no samples are taken\n",
      "311/512 [=================>............] - ETA: 22:21 - rpn_cls: 2.5989 - rpn_regr: 0.4936 - detector_cls: 0.1692 - detector_regr: 0.1339Exception: 'a' cannot be empty unless no samples are taken\n",
      "Exception: 'a' cannot be empty unless no samples are taken\n",
      "385/512 [=====================>........] - ETA: 14:17 - rpn_cls: 2.5975 - rpn_regr: 0.4944 - detector_cls: 0.1686 - detector_regr: 0.1345Exception: 'a' cannot be empty unless no samples are taken\n",
      "434/512 [========================>.....] - ETA: 8:39 - rpn_cls: 2.5983 - rpn_regr: 0.4949 - detector_cls: 0.1686 - detector_regr: 0.1347Exception: 'a' cannot be empty unless no samples are taken\n",
      "448/512 [=========================>....] - ETA: 7:07 - rpn_cls: 2.5981 - rpn_regr: 0.4949 - detector_cls: 0.1686 - detector_regr: 0.1348Exception: 'a' cannot be empty unless no samples are taken\n",
      "497/512 [============================>.] - ETA: 1:40 - rpn_cls: 2.5985 - rpn_regr: 0.4941 - detector_cls: 0.1689 - detector_regr: 0.1355Exception: 'a' cannot be empty unless no samples are taken\n",
      "512/512 [==============================] - 3413s 7s/step - rpn_cls: 2.5988 - rpn_regr: 0.4939 - detector_cls: 0.1690 - detector_regr: 0.1357\n",
      "Mean number of bounding boxes from RPN overlapping ground truth boxes: 1.4381443298969072\n",
      "Classifier accuracy for bounding boxes from RPN: 0.94091796875\n",
      "Loss RPN classifier: 2.6006891741796423\n",
      "Loss RPN regression: 0.4849647065343561\n",
      "Loss Detector classifier: 0.1724340482920912\n",
      "Loss Detector regression: 0.1443405343966333\n",
      "Elapsed time: 3413.0971069335938\n",
      "Epoch 8/10\n",
      " 20/512 [>.............................] - ETA: 49:39 - rpn_cls: 1.9675 - rpn_regr: 0.5737 - detector_cls: 0.1032 - detector_regr: 0.1101Exception: 'a' cannot be empty unless no samples are taken\n",
      " 26/512 [>.............................] - ETA: 51:29 - rpn_cls: 2.0337 - rpn_regr: 0.5341 - detector_cls: 0.1117 - detector_regr: 0.1086Exception: 'a' cannot be empty unless no samples are taken\n",
      " 34/512 [>.............................] - ETA: 53:38 - rpn_cls: 2.1069 - rpn_regr: 0.5137 - detector_cls: 0.1284 - detector_regr: 0.1080Average number of overlapping bounding boxes from RPN = 1.482421875 for 512 previous iterations\n",
      " 46/512 [=>............................] - ETA: 50:54 - rpn_cls: 2.1858 - rpn_regr: 0.4928 - detector_cls: 0.1419 - detector_regr: 0.1076Exception: 'a' cannot be empty unless no samples are taken\n",
      " 52/512 [==>...........................] - ETA: 50:21 - rpn_cls: 2.2064 - rpn_regr: 0.4835 - detector_cls: 0.1461 - detector_regr: 0.1078Exception: 'a' cannot be empty unless no samples are taken\n",
      "189/512 [==========>...................] - ETA: 36:30 - rpn_cls: 2.3962 - rpn_regr: 0.5004 - detector_cls: 0.1686 - detector_regr: 0.1228Exception: 'a' cannot be empty unless no samples are taken\n",
      "386/512 [=====================>........] - ETA: 14:02 - rpn_cls: 2.4554 - rpn_regr: 0.5151 - detector_cls: 0.1773 - detector_regr: 0.1343Average number of overlapping bounding boxes from RPN = 1.5859375 for 512 previous iterations\n",
      "391/512 [=====================>........] - ETA: 13:28 - rpn_cls: 2.4551 - rpn_regr: 0.5154 - detector_cls: 0.1773 - detector_regr: 0.1345Exception: 'a' cannot be empty unless no samples are taken\n",
      "399/512 [======================>.......] - ETA: 12:35 - rpn_cls: 2.4545 - rpn_regr: 0.5158 - detector_cls: 0.1774 - detector_regr: 0.1348Exception: 'a' cannot be empty unless no samples are taken\n",
      "467/512 [==========================>...] - ETA: 5:00 - rpn_cls: 2.4525 - rpn_regr: 0.5167 - detector_cls: 0.1775 - detector_regr: 0.1367Exception: 'a' cannot be empty unless no samples are taken\n",
      "512/512 [==============================] - 3378s 7s/step - rpn_cls: 2.4496 - rpn_regr: 0.5166 - detector_cls: 0.1778 - detector_regr: 0.1376\n",
      "Mean number of bounding boxes from RPN overlapping ground truth boxes: 1.5073041168658698\n",
      "Classifier accuracy for bounding boxes from RPN: 0.93890380859375\n",
      "Loss RPN classifier: 2.4378734339462556\n",
      "Loss RPN regression: 0.5107012067683172\n",
      "Loss Detector classifier: 0.18076929532662112\n",
      "Loss Detector regression: 0.1472397839744417\n",
      "Elapsed time: 3378.2065122127533\n",
      "Total loss decreased from 3.2992737938677648 to 3.2765837200156356, saving weights\n",
      "Epoch 9/10\n",
      " 57/512 [==>...........................] - ETA: 45:21 - rpn_cls: 2.3497 - rpn_regr: 0.4338 - detector_cls: 0.1080 - detector_regr: 0.1206Exception: 'a' cannot be empty unless no samples are taken\n",
      "119/512 [=====>........................] - ETA: 41:48 - rpn_cls: 2.3840 - rpn_regr: 0.4673 - detector_cls: 0.1250 - detector_regr: 0.1237Exception: 'a' cannot be empty unless no samples are taken\n",
      "125/512 [======>.......................] - ETA: 41:42 - rpn_cls: 2.3866 - rpn_regr: 0.4698 - detector_cls: 0.1268 - detector_regr: 0.1239Exception: 'a' cannot be empty unless no samples are taken\n",
      "161/512 [========>.....................] - ETA: 39:43 - rpn_cls: 2.3869 - rpn_regr: 0.4794 - detector_cls: 0.1348 - detector_regr: 0.1247Exception: 'a' cannot be empty unless no samples are taken\n",
      "192/512 [==========>...................] - ETA: 36:11 - rpn_cls: 2.3777 - rpn_regr: 0.4845 - detector_cls: 0.1401 - detector_regr: 0.1264Exception: 'a' cannot be empty unless no samples are taken\n",
      "217/512 [===========>..................] - ETA: 33:02 - rpn_cls: 2.3754 - rpn_regr: 0.4876 - detector_cls: 0.1437 - detector_regr: 0.1279Average number of overlapping bounding boxes from RPN = 1.390625 for 512 previous iterations\n",
      "286/512 [===============>..............] - ETA: 25:05 - rpn_cls: 2.3727 - rpn_regr: 0.4990 - detector_cls: 0.1487 - detector_regr: 0.1304Exception: 'a' cannot be empty unless no samples are taken\n",
      "418/512 [=======================>......] - ETA: 10:32 - rpn_cls: 2.3873 - rpn_regr: 0.5096 - detector_cls: 0.1542 - detector_regr: 0.1332Exception: 'a' cannot be empty unless no samples are taken\n",
      "430/512 [========================>.....] - ETA: 9:14 - rpn_cls: 2.3905 - rpn_regr: 0.5102 - detector_cls: 0.1547 - detector_regr: 0.1334Exception: 'a' cannot be empty unless no samples are taken\n",
      "512/512 [==============================] - 3492s 7s/step - rpn_cls: 2.4075 - rpn_regr: 0.5135 - detector_cls: 0.1575 - detector_regr: 0.1345\n",
      "Mean number of bounding boxes from RPN overlapping ground truth boxes: 1.267766497461929\n",
      "Classifier accuracy for bounding boxes from RPN: 0.9420166015625\n",
      "Loss RPN classifier: 2.484586426968375\n",
      "Loss RPN regression: 0.5300851710335337\n",
      "Loss Detector classifier: 0.17363057602473608\n",
      "Loss Detector regression: 0.1385068920650383\n",
      "Elapsed time: 3492.522093772888\n",
      "Epoch 10/10\n",
      " 28/512 [>.............................] - ETA: 59:10 - rpn_cls: 2.3196 - rpn_regr: 0.4488 - detector_cls: 0.1478 - detector_regr: 0.1004Average number of overlapping bounding boxes from RPN = 1.1015625 for 512 previous iterations\n",
      "173/512 [=========>....................] - ETA: 37:11 - rpn_cls: 2.3202 - rpn_regr: 0.5374 - detector_cls: 0.1458 - detector_regr: 0.1111Exception: 'a' cannot be empty unless no samples are taken\n",
      "341/512 [==================>...........] - ETA: 19:44 - rpn_cls: 2.3993 - rpn_regr: 0.5180 - detector_cls: 0.1516 - detector_regr: 0.1149Exception: 'a' cannot be empty unless no samples are taken\n",
      "365/512 [====================>.........] - ETA: 16:47 - rpn_cls: 2.3989 - rpn_regr: 0.5155 - detector_cls: 0.1521 - detector_regr: 0.1153Average number of overlapping bounding boxes from RPN = 1.326171875 for 512 previous iterations\n",
      "489/512 [===========================>..] - ETA: 2:37 - rpn_cls: 2.4121 - rpn_regr: 0.5054 - detector_cls: 0.1528 - detector_regr: 0.1158Exception: 'a' cannot be empty unless no samples are taken\n",
      "512/512 [==============================] - 3493s 7s/step - rpn_cls: 2.4156 - rpn_regr: 0.5040 - detector_cls: 0.1526 - detector_regr: 0.1157\n",
      "Mean number of bounding boxes from RPN overlapping ground truth boxes: 1.1414141414141414\n",
      "Classifier accuracy for bounding boxes from RPN: 0.95147705078125\n",
      "Loss RPN classifier: 2.4985082332727093\n",
      "Loss RPN regression: 0.47310349051440426\n",
      "Loss Detector classifier: 0.14798386036078887\n",
      "Loss Detector regression: 0.11231395270758071\n",
      "Elapsed time: 3493.0433356761932\n",
      "Total loss decreased from 3.2765837200156356 to 3.231909536855483, saving weights\n",
      "Training complete, exiting.\n"
     ]
    }
   ],
   "source": [
    "\n",
    "for epoch_num in range(num_epochs):\n",
    "#     i=0\n",
    "    progbar = generic_utils.Progbar(epoch_length)  \n",
    "    print('Epoch {}/{}'.format(epoch_num + 1, num_epochs))\n",
    "\n",
    "    while True:\n",
    "        try:\n",
    "            if len(rpn_accuracy_rpn_monitor) == epoch_length and verbose:\n",
    "                mean_overlapping_bboxes = float(sum(rpn_accuracy_rpn_monitor))/len(rpn_accuracy_rpn_monitor)\n",
    "                rpn_accuracy_rpn_monitor = []\n",
    "                print('Average number of overlapping bounding boxes from RPN = {} for {} previous iterations'.format(mean_overlapping_bboxes, epoch_length))\n",
    "                if mean_overlapping_bboxes == 0:\n",
    "                    print('RPN is not producing bounding boxes that overlap the ground truth boxes. Check RPN settings or keep training.')\n",
    "\n",
    "            X, Y, img_data = next(data_gen_train)\n",
    "            loss_rpn = model_rpn.train_on_batch(X, Y)\n",
    "            write_log(callback, ['rpn_cls_loss', 'rpn_reg_loss'], loss_rpn, train_step)\n",
    "\n",
    "            P_rpn = model_rpn.predict_on_batch(X)\n",
    "            R = roi_helpers.rpn_to_roi(P_rpn[0], P_rpn[1], K.image_dim_ordering(), use_regr=True, overlap_thresh=0.7, max_boxes=300)\n",
    "            X2, Y1, Y2, IouS = roi_helpers.calc_iou(R, img_data, class_mapping)\n",
    "            if X2 is None:\n",
    "                rpn_accuracy_rpn_monitor.append(0)\n",
    "                rpn_accuracy_for_epoch.append(0)\n",
    "                continue\n",
    "\n",
    "            # sampling positive/negative samples\n",
    "            neg_samples = np.where(Y1[0, :, -1] == 1)\n",
    "            pos_samples = np.where(Y1[0, :, -1] == 0)\n",
    "            if len(neg_samples) > 0:\n",
    "                neg_samples = neg_samples[0]\n",
    "            else:\n",
    "                neg_samples = []\n",
    "\n",
    "            if len(pos_samples) > 0:\n",
    "                pos_samples = pos_samples[0]\n",
    "            else:\n",
    "                pos_samples = []\n",
    "\n",
    "            rpn_accuracy_rpn_monitor.append(len(pos_samples))\n",
    "            rpn_accuracy_for_epoch.append((len(pos_samples)))\n",
    "\n",
    "            if num_rois > 1:\n",
    "                if len(pos_samples) < num_rois//2:\n",
    "                    selected_pos_samples = pos_samples.tolist()\n",
    "                else:\n",
    "                    selected_pos_samples = np.random.choice(pos_samples, num_rois//2, replace=False).tolist()\n",
    "                try:\n",
    "                    selected_neg_samples = np.random.choice(\n",
    "                        neg_samples, num_rois - len(selected_pos_samples), replace=False).tolist()\n",
    "                except ValueError:\n",
    "                    selected_neg_samples = np.random.choice(\n",
    "                        neg_samples, num_rois - len(selected_pos_samples), replace=True).tolist()\n",
    "\n",
    "                sel_samples = selected_pos_samples + selected_neg_samples\n",
    "            else:\n",
    "\n",
    "                selected_pos_samples = pos_samples.tolist()\n",
    "                selected_neg_samples = neg_samples.tolist()\n",
    "                if np.random.randint(0, 2):\n",
    "                    sel_samples = random.choice(neg_samples)\n",
    "                else:\n",
    "                    sel_samples = random.choice(pos_samples)\n",
    "            loss_class = model_classifier.train_on_batch([X, X2[:, sel_samples, :]], [Y1[:, sel_samples, :], Y2[:, sel_samples, :]])\n",
    "            write_log(callback, ['detection_cls_loss', 'detection_reg_loss', 'detection_acc'], loss_class, train_step)\n",
    "            train_step += 1\n",
    "\n",
    "            losses[iter_num, 0] = loss_rpn[1]\n",
    "            losses[iter_num, 1] = loss_rpn[2]\n",
    "\n",
    "            losses[iter_num, 2] = loss_class[1]\n",
    "            losses[iter_num, 3] = loss_class[2]\n",
    "            losses[iter_num, 4] = loss_class[3]\n",
    "\n",
    "            iter_num += 1\n",
    "\n",
    "            progbar.update(iter_num, [('rpn_cls', np.mean(losses[:iter_num, 0])), ('rpn_regr', np.mean(losses[:iter_num, 1])),\n",
    "                                      ('detector_cls', np.mean(losses[:iter_num, 2])), ('detector_regr', np.mean(losses[:iter_num, 3]))])\n",
    "            if iter_num == epoch_length:\n",
    "                loss_rpn_cls = np.mean(losses[:, 0])\n",
    "                loss_rpn_regr = np.mean(losses[:, 1])\n",
    "                loss_class_cls = np.mean(losses[:, 2])\n",
    "                loss_class_regr = np.mean(losses[:, 3])\n",
    "                class_acc = np.mean(losses[:, 4])\n",
    "\n",
    "                mean_overlapping_bboxes = float(sum(rpn_accuracy_for_epoch)) / len(rpn_accuracy_for_epoch)\n",
    "                rpn_accuracy_for_epoch = []\n",
    "\n",
    "                \n",
    "                print('Mean number of bounding boxes from RPN overlapping ground truth boxes: {}'.format(mean_overlapping_bboxes))\n",
    "                print('Classifier accuracy for bounding boxes from RPN: {}'.format(class_acc))\n",
    "                print('Loss RPN classifier: {}'.format(loss_rpn_cls))\n",
    "                print('Loss RPN regression: {}'.format(loss_rpn_regr))\n",
    "                print('Loss Detector classifier: {}'.format(loss_class_cls))\n",
    "                print('Loss Detector regression: {}'.format(loss_class_regr))\n",
    "                print('Elapsed time: {}'.format(time.time() - start_time))\n",
    "\n",
    "                curr_loss = loss_rpn_cls + loss_rpn_regr + loss_class_cls + loss_class_regr\n",
    "                iter_num = 0\n",
    "                start_time = time.time()\n",
    "\n",
    "                write_log(callback,\n",
    "                          ['Elapsed_time', 'mean_overlapping_bboxes', 'mean_rpn_cls_loss', 'mean_rpn_reg_loss',\n",
    "                           'mean_detection_cls_loss', 'mean_detection_reg_loss', 'mean_detection_acc', 'total_loss'],\n",
    "                          [time.time() - start_time, mean_overlapping_bboxes, loss_rpn_cls, loss_rpn_regr,\n",
    "                           loss_class_cls, loss_class_regr, class_acc, curr_loss],\n",
    "                          epoch_num)\n",
    "\n",
    "                if curr_loss < best_loss:\n",
    "                    if verbose:\n",
    "                        print('Total loss decreased from {} to {}, saving weights'.format(best_loss,curr_loss))\n",
    "                    best_loss = curr_loss\n",
    "                    model_all.save_weights(model_path)\n",
    "\n",
    "                break\n",
    "\n",
    "        except Exception as e:\n",
    "            print('Exception: {}'.format(e))\n",
    "            continue\n",
    "\n",
    "print('Training complete, exiting.')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-20T05:38:54.045390Z",
     "start_time": "2019-10-20T05:38:54.039904Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'bg': 1, 'face': 0}\n"
     ]
    }
   ],
   "source": [
    "print(class_mapping)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 测试网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-22T06:37:43.472796Z",
     "start_time": "2019-10-22T06:37:43.466988Z"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import cv2\n",
    "import numpy as np\n",
    "import sys\n",
    "import pickle\n",
    "import time\n",
    "import resnet60_Copy1 as nn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-22T06:37:44.293237Z",
     "start_time": "2019-10-22T06:37:44.287184Z"
    }
   },
   "outputs": [],
   "source": [
    "num_rois = 32\n",
    "img_path = test_path = \"./images\"\n",
    "network = \"resnet50\"\n",
    "use_horizontal_flips = False\n",
    "use_vertical_flips = False\n",
    "rot_90 = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-22T06:37:45.013407Z",
     "start_time": "2019-10-22T06:37:44.992303Z"
    }
   },
   "outputs": [],
   "source": [
    "def format_img_size(img):\n",
    "    \"\"\" formats the image size based on config \"\"\"\n",
    "    img_min_side = float(im_size)\n",
    "    (height, width ,_) = img.shape\n",
    "\n",
    "    if width <= height:\n",
    "        ratio = img_min_side/width\n",
    "        new_height = int(ratio * height)\n",
    "        new_width = int(img_min_side)\n",
    "    else:\n",
    "        ratio = img_min_side/height\n",
    "        new_width = int(ratio * width)\n",
    "        new_height = int(img_min_side)\n",
    "    img = cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_CUBIC)\n",
    "    return img, ratio\n",
    "\n",
    "def format_img_channels(img):\n",
    "    \"\"\" formats the image channels based on config \"\"\"\n",
    "    img = img[:, :, (2, 1, 0)]\n",
    "    img = img.astype(np.float32)\n",
    "    img[:, :, 0] -= img_channel_mean[0]\n",
    "    img[:, :, 1] -= img_channel_mean[1]\n",
    "    img[:, :, 2] -= img_channel_mean[2]\n",
    "    img /= img_scaling_factor\n",
    "    img = np.transpose(img, (2, 0, 1))\n",
    "    img = np.expand_dims(img, axis=0)\n",
    "    return img\n",
    "\n",
    "def format_img(img):\n",
    "    \"\"\" formats an image for model prediction based on config \"\"\"\n",
    "    img, ratio = format_img_size(img)\n",
    "    img = format_img_channels(img)\n",
    "    return img, ratio\n",
    "\n",
    "# Method to transform the coordinates of the bounding box to its original size\n",
    "def get_real_coordinates(ratio, x1, y1, x2, y2):\n",
    "\n",
    "    real_x1 = int(round(x1 // ratio))\n",
    "    real_y1 = int(round(y1 // ratio))\n",
    "    real_x2 = int(round(x2 // ratio))\n",
    "    real_y2 = int(round(y2 // ratio))\n",
    "\n",
    "    return (real_x1, real_y1, real_x2 ,real_y2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-22T06:37:45.794084Z",
     "start_time": "2019-10-22T06:37:45.783568Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{0: 'face', 1: 'bg'}\n"
     ]
    }
   ],
   "source": [
    "if 'bg' not in class_mapping:\n",
    "    class_mapping['bg'] = len(class_mapping)\n",
    "\n",
    "class_mapping = {v: k for k, v in class_mapping.items()}\n",
    "print(class_mapping)\n",
    "class_to_color = {class_mapping[v]: np.random.randint(0, 255, 3) for v in class_mapping}\n",
    "num_rois = int(num_rois)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-22T06:37:54.104054Z",
     "start_time": "2019-10-22T06:37:46.415817Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loading weights from ./model_frcnn_resnet_face.hdf5\n"
     ]
    }
   ],
   "source": [
    "num_features = 1024\n",
    "\n",
    "if K.image_dim_ordering() == 'th':\n",
    "    input_shape_img = (3, None, None)\n",
    "    input_shape_features = (num_features, None, None)\n",
    "else:\n",
    "    input_shape_img = (None, None, 3)\n",
    "    input_shape_features = (None, None, num_features)\n",
    "\n",
    "\n",
    "img_input = Input(shape=input_shape_img)\n",
    "roi_input = Input(shape=(num_rois, 4))\n",
    "feature_map_input = Input(shape=input_shape_features)\n",
    "\n",
    "# define the base network (resnet here, can be VGG, Inception, etc)\n",
    "shared_layers = nn.nn_base(img_input, trainable=True)\n",
    "\n",
    "# define the RPN, built on the base layers\n",
    "num_anchors = len(anchor_box_scales) * len(anchor_box_ratios)\n",
    "rpn_layers = nn.rpn(shared_layers, num_anchors)\n",
    "\n",
    "classifier = nn.classifier(feature_map_input, roi_input, num_rois, nb_classes=len(class_mapping), trainable=True)\n",
    "\n",
    "model_rpn = Model(img_input, rpn_layers)\n",
    "model_classifier_only = Model([feature_map_input, roi_input], classifier)\n",
    "\n",
    "model_classifier = Model([feature_map_input, roi_input], classifier)\n",
    "\n",
    "print('Loading weights from {}'.format(model_path))\n",
    "model_rpn.load_weights(model_path, by_name=True)\n",
    "model_classifier.load_weights(model_path, by_name=True)\n",
    "\n",
    "model_rpn.compile(optimizer='sgd', loss='mse')\n",
    "model_classifier.compile(optimizer='sgd', loss='mse')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-22T06:37:54.109566Z",
     "start_time": "2019-10-22T06:37:54.106529Z"
    }
   },
   "outputs": [],
   "source": [
    "import roi_helpers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-10-22T06:38:15.054512Z",
     "start_time": "2019-10-22T06:37:54.112983Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "000019.jpg\n",
      "Elapsed time = 5.307029485702515\n",
      "[('face', 86.7138922214508), ('face', 85.2389931678772), ('face', 84.98808741569519), ('face', 84.94347929954529), ('face', 84.8703384399414), ('face', 84.22408103942871), ('face', 84.04393792152405), ('face', 82.62569308280945), ('face', 82.55789875984192), ('face', 82.01550841331482), ('face', 82.00750350952148), ('face', 81.86426162719727), ('face', 80.25766611099243)]\n",
      "000035.jpg\n",
      "Elapsed time = 1.7163968086242676\n",
      "[]\n",
      "000042.jpg\n",
      "Elapsed time = 1.7037813663482666\n",
      "[('face', 96.78489565849304), ('face', 95.85571885108948), ('face', 95.75632214546204), ('face', 95.71045637130737), ('face', 95.23939490318298), ('face', 95.23172974586487), ('face', 95.03504037857056), ('face', 94.97754573822021), ('face', 93.91996264457703), ('face', 93.74068975448608), ('face', 93.40457320213318), ('face', 92.2070860862732), ('face', 92.20249652862549), ('face', 91.78354740142822), ('face', 91.65956974029541), ('face', 91.41749143600464), ('face', 91.40310883522034), ('face', 90.54083824157715), ('face', 90.52651524543762), ('face', 90.41005373001099), ('face', 90.01889824867249), ('face', 89.95378613471985), ('face', 89.5495593547821), ('face', 89.48753476142883), ('face', 89.45072889328003), ('face', 89.17275667190552), ('face', 88.70691061019897), ('face', 88.14031481742859), ('face', 88.12982439994812), ('face', 87.60089874267578), ('face', 87.52734065055847), ('face', 86.14009022712708), ('face', 86.11310124397278), ('face', 85.18390655517578), ('face', 85.03130078315735), ('face', 84.09728407859802), ('face', 83.30572247505188), ('face', 83.28983187675476), ('face', 82.92474150657654), ('face', 82.76031613349915), ('face', 82.69349932670593), ('face', 82.67654776573181), ('face', 82.3362648487091), ('face', 82.03991651535034), ('face', 81.88170790672302), ('face', 80.21693825721741)]\n",
      "000052.jpg\n",
      "Elapsed time = 1.649561882019043\n",
      "[('face', 93.64997744560242), ('face', 91.34620428085327), ('face', 87.53635287284851), ('face', 87.46688961982727), ('face', 83.75731706619263), ('face', 82.9978346824646), ('face', 82.23164677619934), ('face', 82.02763795852661), ('face', 81.30015730857849), ('face', 81.2641441822052)]\n",
      "000075.jpg\n",
      "Elapsed time = 1.7089312076568604\n",
      "[('face', 95.40196657180786), ('face', 94.54558491706848), ('face', 92.07374453544617), ('face', 91.64959788322449), ('face', 89.29194808006287), ('face', 88.40689063072205), ('face', 86.75834536552429), ('face', 86.26969456672668), ('face', 86.13420128822327), ('face', 85.862797498703), ('face', 83.59370827674866), ('face', 82.73717761039734)]\n",
      "000087.jpg\n",
      "Elapsed time = 1.7041728496551514\n",
      "[('face', 96.9653844833374), ('face', 95.59959173202515), ('face', 95.17614841461182), ('face', 92.21947193145752), ('face', 91.3752794265747), ('face', 90.80221056938171), ('face', 90.4296875), ('face', 89.81851935386658), ('face', 89.81627821922302), ('face', 89.62551951408386), ('face', 89.31690454483032), ('face', 88.94326090812683), ('face', 88.7755036354065), ('face', 88.3118748664856), ('face', 85.68638563156128), ('face', 84.59802269935608), ('face', 83.35945010185242), ('face', 82.66106247901917), ('face', 82.26864337921143)]\n",
      "000088.jpg\n",
      "Elapsed time = 1.6460614204406738\n",
      "[]\n",
      "000089.jpg\n",
      "Elapsed time = 1.7254753112792969\n",
      "[('face', 98.0412483215332), ('face', 97.08781838417053), ('face', 97.0298171043396), ('face', 96.38428688049316), ('face', 96.28686308860779), ('face', 95.58387398719788), ('face', 95.43420076370239), ('face', 95.32553553581238), ('face', 95.29482126235962), ('face', 95.06827592849731), ('face', 94.64929699897766), ('face', 94.3182647228241), ('face', 94.19115781784058), ('face', 94.15748715400696), ('face', 94.02273893356323), ('face', 93.9180076122284), ('face', 93.61299276351929), ('face', 93.58282089233398), ('face', 93.31152439117432), ('face', 93.25117468833923), ('face', 93.24583411216736), ('face', 93.16418170928955), ('face', 93.1638777256012), ('face', 93.03204417228699), ('face', 92.89708733558655), ('face', 92.84554719924927), ('face', 92.73936748504639), ('face', 92.53737330436707), ('face', 92.50665307044983), ('face', 92.23222136497498), ('face', 91.92006587982178), ('face', 91.83788299560547), ('face', 91.1902666091919), ('face', 90.79900979995728), ('face', 90.57790040969849), ('face', 90.46331644058228), ('face', 90.15920162200928), ('face', 90.05077481269836), ('face', 89.9758517742157), ('face', 89.9068534374237), ('face', 89.22088146209717), ('face', 88.97521495819092), ('face', 88.97485733032227), ('face', 88.89734148979187), ('face', 88.82713317871094), ('face', 88.73645067214966), ('face', 88.58054876327515), ('face', 88.40711116790771), ('face', 88.39595317840576), ('face', 88.19444179534912), ('face', 88.06548118591309), ('face', 87.68420815467834), ('face', 87.59986758232117), ('face', 86.66191101074219), ('face', 86.63213849067688), ('face', 85.96978187561035), ('face', 85.94483733177185), ('face', 85.81293225288391), ('face', 85.72189807891846), ('face', 85.09532809257507), ('face', 84.80936288833618), ('face', 84.57264304161072), ('face', 83.90420079231262), ('face', 83.5650086402893), ('face', 82.18213319778442), ('face', 82.18161463737488), ('face', 82.1010947227478), ('face', 81.46068453788757), ('face', 80.86413145065308), ('face', 80.8106541633606), ('face', 80.25723099708557), ('face', 80.03191351890564)]\n",
      "000090.jpg\n",
      "Elapsed time = 1.7249631881713867\n",
      "[('face', 98.72036576271057), ('face', 93.65259408950806), ('face', 92.24175214767456), ('face', 90.98089933395386), ('face', 89.87588286399841), ('face', 89.02367949485779), ('face', 86.26973032951355), ('face', 85.86985468864441), ('face', 83.97876620292664), ('face', 81.2528669834137), ('face', 80.88701367378235)]\n",
      "000100.jpg\n",
      "Elapsed time = 1.5902395248413086\n",
      "[('face', 89.11439776420593), ('face', 84.44241285324097), ('face', 80.67792057991028)]\n"
     ]
    }
   ],
   "source": [
    "all_imgs = []\n",
    "\n",
    "classes = {}\n",
    "\n",
    "bbox_threshold = 0.8\n",
    "\n",
    "visualise = True\n",
    "\n",
    "for idx, img_name in enumerate(sorted(os.listdir(img_path))):\n",
    "    if not img_name.lower().endswith(('.bmp', '.jpeg', '.jpg', '.png', '.tif', '.tiff')):\n",
    "        continue\n",
    "    print(img_name)\n",
    "    st = time.time()\n",
    "    filepath = os.path.join(img_path,img_name)\n",
    "\n",
    "    img = cv2.imread(filepath)\n",
    "\n",
    "    X, ratio = format_img(img)\n",
    "\n",
    "    if K.image_dim_ordering() == 'tf':\n",
    "        X = np.transpose(X, (0, 2, 3, 1))\n",
    "\n",
    "    # get the feature maps and output from the RPN\n",
    "    [Y1, Y2, F] = model_rpn.predict(X)\n",
    "\n",
    "\n",
    "    R = roi_helperfgw.rpn_to_roi(Y1, Y2,  K.image_dim_ordering(), overlap_thresh=0.7)\n",
    "\n",
    "    # convert from (x1,y1,x2,y2) to (x,y,w,h)\n",
    "    R[:, 2] -= R[:, 0]\n",
    "    R[:, 3] -= R[:, 1]\n",
    "\n",
    "    # apply the spatial pyramid pooling to the proposed regions\n",
    "    bboxes = {}\n",
    "    probs = {}\n",
    "\n",
    "    for jk in range(R.shape[0]//num_rois + 1):\n",
    "        ROIs = np.expand_dims(R[num_rois*jk:num_rois*(jk+1), :], axis=0)\n",
    "        if ROIs.shape[1] == 0:\n",
    "            break\n",
    "\n",
    "        if jk == R.shape[0]//num_rois:\n",
    "            #pad R\n",
    "            curr_shape = ROIs.shape\n",
    "            target_shape = (curr_shape[0],num_rois,curr_shape[2])\n",
    "            ROIs_padded = np.zeros(target_shape).astype(ROIs.dtype)\n",
    "            ROIs_padded[:, :curr_shape[1], :] = ROIs\n",
    "            ROIs_padded[0, curr_shape[1]:, :] = ROIs[0, 0, :]\n",
    "            ROIs = ROIs_padded\n",
    "\n",
    "        [P_cls, P_regr] = model_classifier_only.predict([F, ROIs])\n",
    "\n",
    "        for ii in range(P_cls.shape[1]):\n",
    "\n",
    "            if np.max(P_cls[0, ii, :]) < bbox_threshold or np.argmax(P_cls[0, ii, :]) == (P_cls.shape[2] - 1):\n",
    "                continue\n",
    "\n",
    "            cls_name = class_mapping[np.argmax(P_cls[0, ii, :])]\n",
    "\n",
    "            if cls_name not in bboxes:\n",
    "                bboxes[cls_name] = []\n",
    "                probs[cls_name] = []\n",
    "\n",
    "            (x, y, w, h) = ROIs[0, ii, :]\n",
    "\n",
    "            cls_num = np.argmax(P_cls[0, ii, :])\n",
    "            try:\n",
    "                (tx, ty, tw, th) = P_regr[0, ii, 4*cls_num:4*(cls_num+1)]\n",
    "                tx /= classifier_regr_std[0]\n",
    "                ty /= classifier_regr_std[1]\n",
    "                tw /= classifier_regr_std[2]\n",
    "                th /= classifier_regr_std[3]\n",
    "                x, y, w, h = roi_helperfgw.apply_regr(x, y, w, h, tx, ty, tw, th)\n",
    "            except:\n",
    "                pass\n",
    "            bboxes[cls_name].append([rpn_stride*x, rpn_stride*y, rpn_stride*(x+w), rpn_stride*(y+h)])\n",
    "            probs[cls_name].append(np.max(P_cls[0, ii, :]))\n",
    "\n",
    "    all_dets = []\n",
    "\n",
    "    for key in bboxes:\n",
    "        bbox = np.array(bboxes[key])\n",
    "\n",
    "        new_boxes, new_probs = roi_helperfgw.non_max_suppression_fast(bbox, np.array(probs[key]), overlap_thresh=0.5)\n",
    "        for jk in range(new_boxes.shape[0]):\n",
    "            (x1, y1, x2, y2) = new_boxes[jk,:]\n",
    "\n",
    "            (real_x1, real_y1, real_x2, real_y2) = get_real_coordinates(ratio, x1, y1, x2, y2)\n",
    "\n",
    "            cv2.rectangle(img,(real_x1, real_y1), (real_x2, real_y2), (int(class_to_color[key][0]), int(class_to_color[key][1]), int(class_to_color[key][2])),2)\n",
    "\n",
    "            textLabel = '{}: {}'.format(key,int(100*new_probs[jk]))\n",
    "            all_dets.append((key,100*new_probs[jk]))\n",
    "\n",
    "            (retval,baseLine) = cv2.getTextSize(textLabel,cv2.FONT_HERSHEY_COMPLEX,1,1)\n",
    "            textOrg = (real_x1, real_y1-0)\n",
    "\n",
    "            cv2.rectangle(img, (textOrg[0] - 5, textOrg[1]+baseLine - 5), (textOrg[0]+retval[0] + 5, textOrg[1]-retval[1] - 5), (0, 0, 0), 2)\n",
    "            cv2.rectangle(img, (textOrg[0] - 5,textOrg[1]+baseLine - 5), (textOrg[0]+retval[0] + 5, textOrg[1]-retval[1] - 5), (255, 255, 255), -1)\n",
    "            cv2.putText(img, textLabel, textOrg, cv2.FONT_HERSHEY_DUPLEX, 1, (0, 0, 0), 1)\n",
    "\n",
    "    print('Elapsed time = {}'.format(time.time() - st))\n",
    "    print(all_dets)\n",
    "    #cv2.imshow('img', img)\n",
    "    #cv2.waitKey(0)\n",
    "    cv2.imwrite('./results_imgs/{}.png'.format(idx),img)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
